﻿using SwParaPlatform2.logger;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SwParaPlatform2.dlgRuleConfig
{
    public class RuleConfigDelegate : IDelegate
    {
        private readonly IView view;
        private readonly IModel model;
        private readonly ISwParaInterface _commonInterface;
        public RuleConfigDelegate(IView view, IModel model)
        {
            //定义信号
            this.view = view;
            this.model = model;
            _commonInterface = new SwParaInterface();

            this.view.OpenNodeSelected += OnOpenNodeSelected;
            this.view.OpenRuleSetter += OnOpenRuleSetter;
            this.view.DriveTypeChanged += OnDriveTypeChanged;
            this.view.SelectElementChanged += OnSelectElementChanged;
            this.view.OnClearRule += OnClearRule;
            this.view.OnClearComp += OnClearComp;
            this.view.AddRuleConfig += OnAddRuleConfig;
            this.view.LoadDataBtnClicked += OnLoadDataBtnClicked;
            this.view.SelectRow += OnSelectRow;
            this.view.CheckDefaultSelect += CheckDefaultSelect;
            this.view.SaveBtnClicked += OnSaveBtnClicked;
            this.view.DelBtnClicked += OnDelBtnClicked;
            this.view.ChangeBtnClicked += OnChangeBtnClicked;
            this.view.OpenEditEquation += OpenEditEquation;
            view.NextClicked += OnNextClicked;

            this.model.SelectCompChanged += OnSelectCompChanged;
            this.model.SelectDriveTypeChanged += OnSelectDriveTypeChanged;
            this.model.RefreshAllRuleConfigData += OnRefreshAllRuleConfigData;
            this.model.OnSetRuleData += OnSetRuleData;
            this.model.SelectRowChanged += OnSelectRowChanged;
            this.model.OnSelectElementSignal += OnSelectElement;

            //初始化界面
            InitializeDriveTypeList();
            // RefreshTipsShow();
        }

        public void DisConnect()
        {
            this.view.OpenNodeSelected -= OnOpenNodeSelected;
            this.view.OpenRuleSetter -= OnOpenRuleSetter;
            this.view.DriveTypeChanged -= OnDriveTypeChanged;
            this.view.SelectElementChanged -= OnSelectElementChanged;
            this.view.OnClearRule -= OnClearRule;
            this.view.OnClearComp -= OnClearComp;
            this.view.AddRuleConfig -= OnAddRuleConfig;
            this.view.LoadDataBtnClicked -= OnLoadDataBtnClicked;
            this.view.SelectRow -= OnSelectRow;
            this.view.CheckDefaultSelect -= CheckDefaultSelect;
            this.view.SaveBtnClicked -= OnSaveBtnClicked;
            this.view.DelBtnClicked -= OnDelBtnClicked;
            this.view.ChangeBtnClicked -= OnChangeBtnClicked;
            this.view.OpenEditEquation -= OpenEditEquation;
            view.NextClicked -= OnNextClicked;

            this.model.SelectCompChanged -= OnSelectCompChanged;
            this.model.SelectDriveTypeChanged -= OnSelectDriveTypeChanged;
            this.model.RefreshAllRuleConfigData -= OnRefreshAllRuleConfigData;
            this.model.OnSetRuleData -= OnSetRuleData;
            this.model.SelectRowChanged -= OnSelectRowChanged;
            this.model.OnSelectElementSignal -= OnSelectElement;
        }

        public void InitializeDriveTypeList()
        {
            var driveTypeList = model.GetDriveTypeList();
            view.SetDriveTypeList(driveTypeList);
        }

        public void CheckDefaultSelect(object sender, EventArgs e)
        {
            string sMainName = DataStore.Instance.sMainAssemName;
            if(sMainName.EndsWith(".sldprt", StringComparison.OrdinalIgnoreCase))
            {
                string sDefaultSelect = sMainName;
                model.OnSelectCompName(sDefaultSelect);
                view.BanSelectNodeBtn();
            }
        }

        public void OnOpenNodeSelected(object sender, EventArgs e)
        {
            var dFirstSubObj = DataStore.Instance.TreeViewData["SubComp"];
            if (dFirstSubObj is Dictionary<string, object> dFirstSubDict2)
            {
                var dHandleData = DataStore.Instance.ConvertInputData(dFirstSubDict2);
                dlgNodeSelectTree oSelectNodeTreeView = new dlgNodeSelectTree(dHandleData);
                WindowAlignmentHelper.Align(view.DoFindForm(), oSelectNodeTreeView, WindowAlignmentHelper.Alignment.Center);
                oSelectNodeTreeView.NodeSelected += FormB_NodeSelected;
                oSelectNodeTreeView.Show();
            }
        }
        
        public void OnOpenRuleSetter(object sender, EventArgs e)
        {
            Dictionary<string, object> dNestDict = model.GetNestDict();
            List<Dictionary<string, object>> FormulaList = model.GetFormulaList();

            using (dlgFormula.dlgFormulaMain oFormulaMain = new dlgFormula.dlgFormulaMain(dNestDict, FormulaList))
            {
                WindowAlignmentHelper.Align(view.DoFindForm(), oFormulaMain, WindowAlignmentHelper.Alignment.Center);
                if (oFormulaMain.ShowDialog() == DialogResult.OK)
                {
                    // 获取选中的项
                    var dRuleData = oFormulaMain.dDataGridView;
                    model.SetRuleData(dRuleData);
                    
                }
            }
        }

        private void FormB_NodeSelected(object sender, string sSelectNodeName)
        {
            if (sSelectNodeName != null)
            {
                model.OnSelectCompName(sSelectNodeName);
            }
        }
        
        private void RefreshElementList()
        {
            string sSelectComp = model.GetSelectCompName();
            List<string> lMatchList = null;
            view.SetSelectCompName(sSelectComp);

            if(sSelectComp != null && sSelectComp != "")
            {
                var dFirstSubObj = DataStore.Instance.TreeViewData["SubComp"];
                if (dFirstSubObj is Dictionary<string, object> dFirstSubDict2)
                {
                    var dHandleObj = DataStore.Instance.ConvertInputData(dFirstSubDict2)[DataStore.Instance.sMainAssemName];
                    if (dHandleObj is Dictionary<string, object> dHandleData)
                    {
                        var dSubCompObj = dHandleData["SubComp"];
                        if (dSubCompObj is Dictionary<string, object> dSubCompDict)
                        {
                            var dSubCompInfo = DataStore.Instance.ConvertInputData(dSubCompDict)[sSelectComp];
                            var dAllSubCompObj = dSubCompInfo["SubComp"];
                            if (dAllSubCompObj is Dictionary<string, object> dAllSubComp)
                            {
                                var sDriveType = model.GetSelectDriveType();
                                if (sDriveType != null)
                                {
                                    lMatchList = Defines.dRuleDict[sDriveType];
                                }
                                var lElementList = model.GetKeysWithMatchingTypeNames(DataStore.Instance.ConvertInputData(dAllSubComp), lMatchList);
                                
                                view.SetElementList(lElementList);
                            }
                        }
                    }
                }
            }
            else
            {
                var lElementList = new List<string>();
                view.SetElementList(lElementList);
            }
            
            
        }

        public void RefreshTipsShow()
        {
            bool bShow = false;
            string sSelectComp = model.GetSelectCompName();

            view.RefreshTipsShow(bShow);
        }

        public void OnDriveTypeChanged(string selectedType)
        {
            model.OnSelectDriveType(selectedType);

        }
        
        public void OnSelectElementChanged(string sSelectElement)
        {
            Logger.Instance.Log($"选中的元素: {sSelectElement}");
            model.OnSelectElement(sSelectElement);

            var dRuleData = new Dictionary<string, Dictionary<string, object>>();
            model.SetRuleData(dRuleData);

        }
        
        public void OnClearRule(object sender, EventArgs e)
        {
            var dRuleData = new Dictionary<string, Dictionary<string, object>>();
            model.SetRuleData(dRuleData);

        }
        
        public void OnClearComp(object sender, EventArgs e)
        {
            model.OnSelectCompName("");
            CheckDefaultSelect(this, EventArgs.Empty);

        }
        
        public void OnAddRuleConfig(object sender, EventArgs e)
        {
            model.OnAddRuleConfigData();

        }
        
        public void OnSelectDriveTypeChanged()
        {
            view.ClearElement();
            view.ClearRule();
            RefreshElementList();

        } 
        
        public void OnSelectCompChanged()
        {
            view.ClearDriveType();
            view.ClearElement();
            view.ClearRule();
            RefreshElementList();
            RefreshEquationBtnState();

        }

        public void OnSetRuleData()
        {
            var dRuleData = model.GetRuleData();
            string RuleText = "";

            foreach (var RuleInfo in dRuleData)
            {
                string sProp = RuleInfo.Key;
                string sPropRule = (string)RuleInfo.Value["sFormula"];
                RuleText += sProp + ":" + sPropRule;
                RuleText += ";";
            }
            view.OnSetRuleData(RuleText);
        }

        public void OnRefreshAllRuleConfigData()
        {
            view.ClearComp();
            view.ClearRule();

            var dAllRuleGridData = model.GetAllRuleConfigData();

            view.RefreshAllRuleGridData(dAllRuleGridData);//显示

        }

        public void OnNextClicked(object sender, EventArgs e)
        {
            string sFilePath = model.SaveData();
            MainForm parentForm = (MainForm)view.DoFindForm();
            parentForm.isProgrammaticallyClosed = true;
            parentForm.sFilePath = sFilePath;
            parentForm?.Close();
        }
        
        public void OnSaveBtnClicked(object sender, EventArgs e)
        {
            model.SaveData();
        }
        
        public void OnDelBtnClicked(object sender, EventArgs e)
        {
            model.OnDelSelectPara();
        }
        
        public void OnChangeBtnClicked(object sender, EventArgs e)
        {
            model.OnChangeData();
        }

        public void OnLoadDataBtnClicked(object sender, EventArgs e)
        {
            //model.LoadData();
            model.LoadAllData();
        }
        
        public void OpenEditEquation(object sender, EventArgs e)
        {
            string sSelectCompName = model.GetSelectCompName();
            using (dlgFormula.dlgEquation oEquation = new dlgFormula.dlgEquation(sSelectCompName))
            {
                WindowAlignmentHelper.Align(view.DoFindForm(), oEquation, WindowAlignmentHelper.Alignment.Center);
            }
        }

        public void OnSelectRow(object sender, string sSelectPara)
        {
            model.OnSelectRow(sSelectPara);

        }
        
        public void OnSelectElement()
        {
            string sSelectElement = model.GetSelectElement();
            string sSelectCompName = model.GetSelectCompName();
            string sDriveType = model.GetSelectDriveType();
            List<string> EquationNames = _commonInterface.GetEquationNames(sSelectCompName);

            bool bLimit = sDriveType != "方程式常量" && EquationNames.Contains(sSelectElement);
            bool bShowBtn = !bLimit && !string.IsNullOrEmpty(sSelectElement);

            view.RefreshRuleBtnState(bShowBtn);
            view.RefreshTipsShow(bLimit);
        }
        public void OnSelectRowChanged()
        {
            var dAllRuleConfigData = model.GetAllRuleConfigData();
            string sSelectElementFullPath = model.GetSelectElementFullPath();
            var dSelectRuleConfigData = dAllRuleConfigData[sSelectElementFullPath];
            string sSelectCompName = (string)dSelectRuleConfigData["CompName"];
            string sDriveType = (string)dSelectRuleConfigData["DriveType"];
            string sElement = (string)dSelectRuleConfigData["Element"];
            var dRule = new Dictionary<string, Dictionary<string, object>>();

            if(dSelectRuleConfigData["Rule"] is Dictionary<string, Dictionary<string, object>>)
            {
                dRule = (Dictionary<string, Dictionary<string, object>>)dSelectRuleConfigData["Rule"];
            }
            else
            {
                dRule = _commonInterface.ConvertToNestedDictionary((Dictionary<string, object>)dSelectRuleConfigData["Rule"]);
            }

            if(DataStore.Instance.dName_NoteData.TryGetValue(sElement, out var oNote))
            {
                sElement = (string)oNote;
            }

            model.OnSelectCompName(sSelectCompName); //理论上可以去掉这步

            view.LoadSelectDriveType(sDriveType);
            view.LoadSelectElement(sElement);

            model.SetRuleData(dRule);

        }

        public void RefreshEquationBtnState()
        {
            string sSelectCompName = model.GetSelectCompName();
            bool bEnable = DataStore.Instance.EquationData.ContainsKey(sSelectCompName);
            view.RefreshEquationBtnState(bEnable);
        }

    }
}
